
import 'package:flutter/material.dart';
import 'dart:ui' as ui;

///https://cloud.tencent.com/developer/article/2113870?areaSource=102001.4&traceId=i4uF4TB0-9DMiSSQj4No5
///
///绘制图片  处理图片  添加水印信息
///
///
class PaperPainter extends CustomPainter{

  Paint? _paint;
  final double strokeWidth = 0.5;
  final Color color = Colors.blue;

  final image;

  PaperPainter(this.image) {
    _paint = Paint()
      ..style = PaintingStyle.fill
      ..strokeWidth = strokeWidth
      ..color = color;
  }

  @override
  void paint(Canvas canvas, Size size) {
    print("size===${size.width}     ${size.height}");
    // canvas.translate(size.width / 2, size.height / 2);
    _drawImage(canvas);
    // _drawTextWithParagraph(canvas,TextAlign.center);
    // _drawTextPaintShowSize(canvas);
    // _drawTextPaintWithPaint(canvas);
    // _drawText(canvas,size);
    // _drawImageRect(canvas);
    // _drawImageNine(canvas);
    // _drawText(canvas,size);
  }

  @override
  bool shouldRepaint(PaperPainter oldDelegate) =>
      image != oldDelegate.image;

  ///绘制图片
  void _drawImage(Canvas canvas) {
    if (image != null) {
      canvas.drawImage(
          image, Offset(-image.width / 2, -image.height / 2), _paint!);
    }
  }

  ///绘制图片域
  void _drawImageRect(Canvas canvas) {
    if (image != null) {
      canvas.drawImageRect(
          image,
          Rect.fromCenter(
              center: Offset(image.width/2, image.height/2), width: 60, height: 60),
          Rect.fromLTRB(0, 0, 100, 100).translate(200, 0),
          _paint!);

      canvas.drawImageRect(
          image,
          Rect.fromCenter(
              center: Offset(image.width/2, image.height/2-60), width: 60, height: 60),
          Rect.fromLTRB(0, 0, 100, 100).translate(-280, -100),
          _paint!);

      canvas.drawImageRect(
          image,
          Rect.fromCenter(
              center: Offset(image.width/2+60, image.height/2), width: 60, height: 60),
          Rect.fromLTRB(0, 0, 100, 100).translate(-280, 50),
          _paint!);
    }
  }

  ///图片 .9 域绘制
  void _drawImageNine(Canvas canvas) {
    if (image != null) {
      canvas.drawImageNine(
          image,
          Rect.fromCenter(center: Offset(image.width/2, image.height-6.0),
              width: image.width-20.0, height: 2.0),
          Rect.fromCenter(center: Offset(0, 0,), width:300, height: 120),
          _paint!);

      canvas.drawImageNine(
          image,
          Rect.fromCenter(center: Offset(image.width/2, image.height-6.0),
              width: image.width-20.0, height: 2.0),
          Rect.fromCenter(center: Offset(0, 0,), width:100, height: 50).translate(250, 0),
          _paint!);

      canvas.drawImageNine(
          image,
          Rect.fromCenter(center: Offset(image.width/2, image.height-6.0),
              width: image.width-20.0, height: 2.0),
          Rect.fromCenter(center: Offset(0, 0,), width:80, height: 250).translate(-250, 0),
          _paint!);
    }
  }

  /// drawParagraph绘制文字
  /// 通过 ParagraphBuilder 构造基本样式 pushStyle 和添加文字addText。
  /// builder.build() 可以创建 Paragraph 对象，之后必须对其排布layout 限制区域。
  /// 下面蓝色区域是绘制的辅助， 依次是左对齐、居中、右对齐
  void _drawTextWithParagraph(Canvas canvas,TextAlign textAlign) {
    var builder = ui.ParagraphBuilder(ui.ParagraphStyle(
      textAlign: textAlign,
      fontSize: 15,
      textDirection: TextDirection.ltr,
      maxLines: 1,
    ));
    builder.pushStyle(
      ui.TextStyle(
          color: Colors.black87, textBaseline: ui.TextBaseline.alphabetic),
    );
    builder.addText("Flutter Unit");
    ui.Paragraph paragraph = builder.build();
    paragraph.layout( ui.ParagraphConstraints(width: 100));
    canvas.drawParagraph(paragraph, Offset(0, 0));
    canvas.drawRect(Rect.fromLTRB(0, 0, 300, 40 ),
        _paint!..color = Colors.blue.withAlpha(33));
  }

  ///TextPainter 绘制文字
  ///TextPainter的绘制基本上就是对drawParagraph的封装，提供了更多的方法，使用起来简洁一些。
  ///所以一般来说都是使用 TextPainter 进行文字绘制。绘制先设置 TextPainter，然后执行 layout() 方法进行布局，
  ///其中可以传入布局区域的最大和最小宽度。通过 paint 方法进行绘制
  void _drawTextPaint(Canvas canvas) {
    var textPainter = TextPainter(
        text: TextSpan(
            text: 'Flutter Unit',
            style: TextStyle(fontSize: 40,color: Colors.black)),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    textPainter.layout(); // 进行布局
    textPainter.paint(canvas, Offset.zero); // 进行绘制
  }

  ///TextPainter 获取文字范围
  ///TextPainter 中可以通过 size 属性获取文字所占区域，注意，获取区域必须在执行 layout 方法之后。
  /// 一但确定范围后，就容易实现将文字中心绘制在画布原点，这一个效果是非常重要的。
  void _drawTextPaintShowSize(Canvas canvas) {
    TextPainter textPainter = TextPainter(
        text: TextSpan(
            children: [
              TextSpan(text: 'hello word'),
              TextSpan(text: '\n\n'),
              TextSpan(text: '2021/12/30'),

            ],
            style: TextStyle(
                fontSize: 13,
                color: Colors.black)),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    textPainter.layout(); // 进行布局
    Size size = textPainter.size; // 尺寸必须在布局后获取
    double lr = 2.0*5.0;///文本左右的间距
    double tb = 2.0*5.0;///文本上下的间距
    double width = size.width+lr;
    double height = size.height+tb;
    ///绘制背景
    canvas.drawRect(
        Rect.fromLTRB(0, 0, width, height)
            .translate(-width / 2, -height / 2),
        _paint!..color = Colors.blue.withAlpha(225));

    ///绘制文本信息  需要使用原来的绘制尺寸
    textPainter.paint(canvas, Offset(-size.width / 2, -size.height / 2));
  }

  ///为文字设置画笔样式
  ///比如设置线型的文字，或为文字添加画笔着色器等。可以使用 TextStyle 中的 foreground 属性提供一个画笔。注意:此属性和 TextStyle#color 属性互斥
  void _drawTextPaintWithPaint(Canvas canvas) {
    Paint textPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    TextPainter textPainter = TextPainter(
        text: TextSpan(
            text: 'Flutter Unit by 张风捷特烈',
            style: TextStyle(
                foreground: textPaint, fontSize: 40)),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    textPainter.layout(maxWidth: 280); // 进行布局
    Size size = textPainter.size; // 尺寸必须在布局后获取
    textPainter.paint(canvas, Offset(-size.width / 2, -size.height / 2));

    canvas.drawRect(
        Rect.fromLTRB(0, 0, size.width, size.height)
            .translate(-size.width / 2, -size.height / 2),
        _paint!..color = Colors.blue.withAlpha(33));
  }

  ///为坐标系添加刻度
  ///这里在之前的坐标系上进行优化。对于 step 过小而导致的刻度密集，这里采取简单的处理方案:
// 当 step < 30 时，第奇数个刻度被忽略。如下是 step = 25 时的坐标系。
  // 定义成员变量
  final TextPainter _textPainter = TextPainter(textDirection: TextDirection.ltr);
// 绘制方法
  void _drawText(Canvas canvas, Size size,{double step=25}) {
    // y > 0 轴 文字
    canvas.save();
    for (int i = 0; i < size.height / 2 / step; i++) {
      if (step < 30 && i.isOdd || i == 0) {
        canvas.translate(0, step);
        continue;
      } else {
        var str = (i * step).toInt().toString();
        _drawAxisText(canvas, str, color: Colors.green);
      }
      canvas.translate(0, step);
    }
    canvas.restore();
    // x > 0 轴 文字
    canvas.save();
    for (int i = 0; i < size.width / 2 / step; i++) {
      if (i == 0) {
        _drawAxisText(canvas, "O", color: Colors.black, x: false);
        canvas.translate(step, 0);
        continue;
      }
      if (step < 30 && i.isOdd) {
        canvas.translate(step, 0);
        continue;
      } else {
        var str = (i * step).toInt().toString();
        _drawAxisText(canvas, str, color: Colors.green, x: true);
      }
      canvas.translate(step, 0);
    }
    canvas.restore();
    // y < 0 轴 文字
    canvas.save();
    for (int i = 0; i < size.height / 2 / step; i++) {
      if (step < 30 && i.isOdd || i == 0) {
        canvas.translate(0, -step);
        continue;
      } else {
        var str = (-i * step).toInt().toString();
        _drawAxisText(canvas, str, color: Colors.green);
      }
      canvas.translate(0, -step);
    }
    canvas.restore();
    // x < 0 轴 文字
    canvas.save();
    for (int i = 0; i < size.width / 2 / step; i++) {
      if (step < 30 && i.isOdd || i == 0) {
        canvas.translate(-step, 0);
        continue;
      } else {
        var str = (-i * step).toInt().toString();
        _drawAxisText(canvas, str, color: Colors.green, x: true);
      }
      canvas.translate(-step, 0);
    }
    canvas.restore();
  }

  void _drawAxisText(Canvas canvas, String str,
      {Color color = Colors.black, bool x = false}) {
    TextSpan text = TextSpan(
        text: str,
        style: TextStyle(  fontSize: 11,  color: color ));
    _textPainter.text = text;
    _textPainter.layout(); // 进行布局

    Size size = _textPainter.size;
    Offset offset = Offset.zero;
    if (x == null) {
      offset = Offset(8, 8);
    } else if (x) {
      offset = Offset(-size.width / 2, size.height / 2);
    } else {
      offset = Offset(size.height / 2, -size.height / 2 + 2);
    }
    _textPainter.paint(canvas, offset);
  }
}